/**
 * Copyright (c) 2010-2011 Pierre LABATUT
 *
 * This file is part of multiple-track-player project.
 *
 * multiple-track-player is free software: you can redistribute it and/or modify it
 * under the terms of its license which may be found in the accompanying
 * LICENSE file or <http://code.google.com/p/multiple-track-player/>.
 */
package multitrack.preload;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.SourceDataLine;

/**
 *
 * @author PYW
 */
class PlayThreadRunnable implements Runnable {

    final int frameStart;
    final SourceDataLine line;
    final AudioBuffer audioBuffer;
    final AudioPlayer player;

    public PlayThreadRunnable(AudioPlayer player, SourceDataLine line, AudioBuffer audioBuffer, int frameStart) {
        this.frameStart = frameStart;
        this.audioBuffer = audioBuffer;
        this.player = player;
        this.line = line;
    }

    @Override
    public void run() {
        try {
            final AudioFormat format = line.getFormat();
            // Chunk buffer used to write data to the line
            final byte[] byteChunk = new byte[line.getBufferSize()];
            final int chunkSizeInSample = byteChunk.length / 2;
            // Chunk buffer to trunk summed data (could be removed by writing a 
            // packing algorythm from int to byte) every location holds a 16 bit 
            // sample
            final short[] shortChunk = new short[chunkSizeInSample];
            // Convert frames to sample
            final int fromSample = frameStart * format.getChannels();
            
            line.start();
            for (int chunkFromSample = fromSample;;) {
                int readed = audioBuffer.read(chunkFromSample, shortChunk.length, shortChunk);
                // Pack and write
                int bytes = Bits.shortToByte(shortChunk, 0, readed, byteChunk, 0, format.isBigEndian());
                if (line.write(byteChunk, 0, bytes) != bytes) {
                    //Should never happend
                    throw new RuntimeException("Unexpected incomplete failure");
                }
                chunkFromSample += readed;
                if (readed < chunkSizeInSample) {
                    break;
                }
            }
            line.drain(); //Wait until the buffer is empty            
            player.stop();
        } catch (InterruptedException ex) {
            Logger.getLogger(AudioPlayer.class.getName()).log(Level.SEVERE, null, ex);
        } catch (RuntimeException ex) {
            //Lise have been stoped, dont care about the state, my interupter may know
        }
    }
}
